package com.xpec.c4.game.utility.wordfilter;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xpec.c4.game.utility.GameUtility;
import com.xpec.c4.game.utility.wordfilter.db.PlayerNameFilterModel;
import com.xpec.c4.service.utility.Utility;

/**
 * 過濾詞的靜態功能集中在這裡
 * @author zhangyuan
 * @version 1.0
 * 
 * C1,C2 友情赞助
 */
public class WordFilters 
{
	/** log4j object */
	private static final Log log = LogFactory.getLog(WordFilters.class);
	
	/**
	 * 聊天用过滤词库
	 * UTF8 non-BOM
	 */
	public static final String CHAT_KEYWORD_FILE = "ChatKeyword.txt";
	// public static final String CHAT_KEYWORD_FILE = "AccountKeyword.txt";

	/**
	 * 创角用过滤词库
	 * UTF8 non-BOM
	 */
	public static final String ACCOUNT_KEYWORD_FILE = "AccountKeyword.txt";

	/**
	 * 帳戶名過濾器
	 */
	private static WordFilter accountWordFilter = new WordFilter();

	/**
	 * 最後更新時間
	 */
	private static long dbPlayerNameWordFilterUpdateTime = 0;
	
	/**
	 * 創角關鍵字過濾器 in 資料庫
	 */
	private static WordFilter dbPlayerNameWordFilter = new WordFilter();
	
	/**
	 * 創角關鍵字過濾器 in 資料庫 (完全比對用)
	 */
	private static HashSet<String> dbPlayerNameFullWordFilter = new HashSet<String>();

	/**
	 * 資料庫創角關鍵字同步鎖物件
	 */
	private static final Object dbPlayerNameWordFilterLock = new Object();

	/**
	 * 聊天過濾器
	 */
	private static WordFilter chatWordFilter = new WordFilter();
	
	/**
	 * 文件根目錄
	 */
	@SuppressWarnings("unused")
	private static String configRoot = null;
	
	
	/**
	 * 重新裝載
	 */
	public static void reloadAccountWordFilter()
	{
		URL url = Utility.getUrl(ACCOUNT_KEYWORD_FILE);
		
		if(url != null){
			WordFilter _accountWordFilter = new WordFilter();
			// _accountWordFilter.loadFromFile(configRoot + ACCOUNT_KEYWORD_FILE);
			_accountWordFilter.loadFromFile(url.getFile(), true);
		
			synchronized(accountWordFilter)
			{
				accountWordFilter = _accountWordFilter;
			}
		}
	}

	/**
	 * 重新裝載
	 */	
	public static void reloadChatWordFilter()
	{
		URL url = Utility.getUrl(CHAT_KEYWORD_FILE);
		
		if(url != null){
			WordFilter _chatWordFilter = new WordFilter();
			// _chatWordFilter.loadFromFile(configRoot + CHAT_KEYWORD_FILE);
			_chatWordFilter.loadFromFile(url.getFile(), false);
		
			synchronized(chatWordFilter)
			{
				chatWordFilter = _chatWordFilter;
			}
		}
	}
	
	/**
	 * 重新裝載 創角關鍵字過濾器 in 資料庫
	 * 
	 * @param updateTime
	 *            更新的時間 (ms)
	 */
	public static void reloadDbPlayerNameFilter(long updateTime) {
		synchronized (dbPlayerNameWordFilterLock) {
			if (updateTime <= dbPlayerNameWordFilterUpdateTime) {
				return;
			}

			dbPlayerNameWordFilterUpdateTime = updateTime;
		}

		// 載入關鍵字列表
		ArrayList<PlayerNameFilterModel> modelList = WordFilterDAO.loadAccountWordsFromDB();

		WordFilter wf = new WordFilter();
		HashSet<String> fwf = new HashSet<String>();

		for (PlayerNameFilterModel model : modelList) {
			if (!GameUtility.isHaveString(model.getWord())) {
				continue;
			}

			switch (model.getCompareType()) {
			case WordCompareType.FUZZY:
				wf.addBadWord(model.getWord().toLowerCase());
				break;
			case WordCompareType.FULL:
				fwf.add(model.getWord().toLowerCase());
				break;
			}
		}

		synchronized (dbPlayerNameWordFilterLock) {
			dbPlayerNameWordFilter = wf;
			dbPlayerNameFullWordFilter = fwf;
		}

		if (log.isInfoEnabled()) {
			log.info("reload db player name filter done.");
		}
	}
	
	/**
	 * 設置根目錄
	 * @param path
	 */
	public static void setRootPath(String path)
	{
		configRoot = path;
	}
	
	/**
	 * 過濾帳戶名等
	 * @param pWord
	 * @return
	 */
	public static String filterAccountKeyword(String pWord)
	{
		synchronized(accountWordFilter)
		{
			return accountWordFilter.pass(accountWordFilter.filterSpace(pWord));
		}
	}
	
	/**
	 * 過濾聊天
	 * @param pWord
	 * @return
	 */
	public static String filterChatKeyword(String pWord)
	{
		synchronized(chatWordFilter)
		{
			return chatWordFilter.pass(pWord);
		}
	}
	
	/**
	 * 過濾角色名稱
	 * 
	 * @param pWord
	 * @return
	 */
	public static String filterDbPlayerNameKeyword(String pWord) {
		WordFilter wf = null;
		HashSet<String> fwf = null;

		synchronized (dbPlayerNameWordFilterLock) {
			wf = dbPlayerNameWordFilter;
			fwf = dbPlayerNameFullWordFilter;
		}

		if (!GameUtility.isHaveString(pWord)) {
			return pWord;
		}

		// 檢查完整比對列表
		if (fwf.contains(pWord.toLowerCase())) {
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < pWord.length(); i++) {
				sb.append("*");
			}
			return sb.toString();
		}

		// 檢查模糊比對列表
		return wf.pass(pWord.toLowerCase());
	}
}
